#pragma once

class CInjectThread
{
    HHOOK m_hook;
    static CInjectThread* pThis;
public:
    CInjectThread():m_hook(NULL)
    {}
    virtual ~CInjectThread(){}
protected:
    bool InitInject(CInjectThread* Param)
    {
        if (m_hook) return 0;
        pThis = Param;//WH_CALLWNDPROCRET
        m_hook = SetWindowsHookEx(WH_CALLWNDPROC, CInjectThread::CallWndRetProc, 0, CWowFun::GetThreadID());
        DWORD dd = GetLastError();
        return true;
    }
    bool Release()
    {
        bool bRet = false;
        if (m_hook)
        {
            bRet = !!UnhookWindowsHookEx(m_hook);
            m_hook = 0;
        }
        return bRet;
    }
    static LRESULT CALLBACK CallWndRetProc(      
    int nCode,
    WPARAM wParam,
    LPARAM lParam)
    {
        pThis->ThreadTime(wParam, lParam);
        return CallNextHookEx(0, nCode, wParam, lParam);
    }
    virtual DWORD ThreadTime(WPARAM wParam, LPARAM lParam)=0;
};

class CEngine:public CInjectThread
{            
public:
    CEngine();
    ~CEngine();
    bool Inject();
    bool Exit();

    bool Init(CString strConfig);
    void stop();
protected:
    void run();
    bool Job();



private:
    DWORD ThreadTime(WPARAM wParam, LPARAM lParam);
    DWORD m_dwTickCount;
    DWORD m_dwTickJump;
    bool m_bState;
};